#define DEBUG
#include <cstdio>

using namespace std;

const int maxn=100000, inf=0x7fffffff;

void swap(int &a, int &b) {
  int t;
  t = a, a = b, b = t;
}

int min(int a, int b) {
  return a<b ? a : b;
}

int max(int a, int b) {
  return a>b ? a : b;
}

class Tree {
public:
  int n, m, ind[maxn+1], to[2*maxn+1], link[2*maxn+1], val[2*maxn+1], col[maxn+1], d[maxn+1], f[maxn+1];

  void init(int n) {
    this->n = n;
    for (int i=1; i<=n; i++) {
      col[i] = i;
    }
  }

  int getCol(int o) {
    return col[o]==o ? o : (col[o] = getCol(col[o]));
  }

  void addSide(int u, int v, int w) {
    m++;
    to[m] = v;
    val[m] = w;
    link[m] = ind[u];
    ind[u] = m;
    col[getCol(u)] = getCol(v);
  }

  void initF(int o, int fa) {
    f[o] = 0;
    for (int i=ind[o]; i; i=link[i]) {
      if (to[i]!=fa) {
	initF(to[i], o);
	f[o] = max(f[o], f[to[i]]+val[i]);
      }
    }
  }

  int calcD(int o, int fa, int len) {
    d[o] = max(f[o], len);
    int first=to[ind[o]], second=to[ind[o]], fv=0, sv=0, ret=0;
    for (int i=ind[o]; i; i=link[i]) {
      if (to[i]!=fa) {
	int t=to[i], tv=f[t]+val[i];
	if (fv<=tv) {
	  swap(tv, fv);
	  swap(first, t);
	}
	if (sv<=tv) {
	  swap(sv, tv);
	  swap(second, t);
	}
      }
    }
    ret = fv+sv;
    for (int i=ind[o]; i; i=link[i]) {
      if (to[i]!=fa) {
	ret = max(ret, calcD(to[i], o, max(len, first==to[i] ? (second==to[i] ? 0 : sv) : fv)+val[i]));
      }
    }
    return ret;
  }
};

int main() {
  freopen("diameter.in", "r", stdin);
  freopen("diameter.out", "w", stdout);

  static Tree tree;
  int n, m, l;
  scanf("%d %d %d", &n, &m, &l);
  tree.init(n);
  for (int i=1; i<=m; i++) {
    int u, v, w;
    scanf("%d %d %d", &u, &v, &w);
    u++, v++;
    tree.addSide(u, v, w);
    tree.addSide(v, u, w);
  }

  int ans=0;
  static int root[maxn+1], mind[maxn+1], maxd[maxn+1];
  for (int i=1; i<=n; i++) {
    if (!root[tree.getCol(i)]) {
      mind[tree.getCol(i)] = inf;
      root[tree.getCol(i)] = i;
      tree.initF(i, 0);
      ans = max(ans, tree.calcD(i, 0, 0));
    }
  }
  
  for (int i=1; i<=n; i++) {
    mind[tree.getCol(i)] = min(mind[tree.getCol(i)], tree.d[i]);
    maxd[tree.getCol(i)] = max(maxd[tree.getCol(i)], tree.d[i]);
    if (maxd[maxd[0]]<maxd[tree.getCol(i)]) {
      maxd[0] = maxd[tree.getCol(i)];
    }
  }

  for (int i=1; i<=n; i++) {
    if (i!=maxd[0]) {
      ans = max(ans, mind[i]+mind[maxd[0]]+l);
    }
  }
  printf("%d", ans);

  fclose(stdin);
  fclose(stdout);
  return 0;
}
